home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1992 / 04 / 386bsd.492 next >
Text File  |  1992-03-18  |  7KB  |  247 lines

  1. _PORTING UNIX TO THE 386_
  2. by William Frederick Jolitz and Lynne Greer Jolitz
  3.  
  4. [LISTING ONE]
  5.  
  6. /* [Excerpted from /sys/i386/isa/icu.h] */
  7.  ...
  8. /* Macro's for interrupt level priority masks (used in assembly code) */
  9. /* mask additional interrupts */
  10. #define ORPL(m) \
  11.     cli ;               /* disable interrupts */ \
  12.     movw    m , %dx ;       /* get the mask */ \
  13.     inb $ IO_ICU1+1, %al ;  /* next, get low order mask */ \
  14.     xchgb   %dl, %al ;      /* switch the old with the new */ \
  15.     orb %dl, %al ;      /* finally, or it in! */ \
  16.     outb    %al, $ IO_ICU1+1 ; \
  17.     inb $0x84, %al ; \
  18.     inb $ IO_ICU2+1, %al ;  /* next, get high order mask */ \
  19.     xchgb   %dh, %al ;      /* switch the old with the new */ \
  20.     orb %dh, %al ;      /* finally, or it in! */ \
  21.     outb    %al, $ IO_ICU2+1    ; \
  22.     inb $0x84, %al ;    /* flush write buffer, delay bus cycle */ \
  23.     movzwl  %dx, %eax ;     /* return old priority */ \
  24.     sti ;               /* enable interrupts */
  25. /* force interrupt mask */
  26. #define SETPL(v)    \
  27.     cli ;               /* disable interrupts */ \
  28.     movw    v , %dx ; \
  29.     inb $ IO_ICU1+1, %al ;  /* next, get low order mask */ \
  30.     xchgb   %dl, %al ;      /* switch the old with the new */ \
  31.     outb    %al, $ IO_ICU1+1 ; \
  32.     inb $0x84, %al ; \
  33.     inb $ IO_ICU2+1, %al ;  /* next, get high order mask */ \
  34.     xchgb   %dh, %al ;      /* switch the copy with the new */ \
  35.     outb    %al, $ IO_ICU2+1    ; \
  36.     inb $0x84, %al ;    /* flush write buffer, delay bus cycle */ \
  37.     movzwl  %dx, %eax ;     /* return old priority */ \
  38.     sti ;               /* enable interrupts */
  39. /* Mask a group of interrupts atomically - interrupt entry */
  40. #define INTR(unit,mask,offst) \
  41.     pushl   $0 ;          /* first, build a trap frame for ... */ \
  42.     pushl   $ T_ASTFLT ;  /* ... possible rescheduling that may occur */ \
  43.     pushal ; \
  44.     nop ; \
  45.     movb    $0x20, %al ;    /* next, as soon as possible send EOI ... */ \
  46.     outb    %al, $ IO_ICU1 ; /* ...so in service bit may be cleared ...*/ \
  47.     inb $0x84, %al ;    /* ... ASAP */ \
  48.     movb    $0x20, %al ;    /* likewise, the other one as well */ \
  49.     outb    %al,$ IO_ICU2 ; \
  50.     inb $0x84,%al ; \
  51.     pushl   %ds ;       /* save our data and extra segments ... */ \
  52.     pushl   %es ; \
  53.     movw    $0x10, %ax ;    /* ... and reload with kernel's own */ \
  54.     movw    %ax, %ds ; \
  55.     movw    %ax, %es ; \
  56.     incl    _cnt+V_INTR ;   /* tally interrupts */ \
  57.     incl    _isa_intr + offst * 4 ; \
  58.     movw    mask , %dx ;    /* assert group mask */ \ 
  59.  
  60.    inb $ IO_ICU1+1, %al ; /* next, get low order mask */ \
  61.     xchgb   %dl, %al ;  /* switch the old with the new */ \
  62.     orb %dl, %al ;  /* finally, or it in! */ \
  63.     outb    %al, $ IO_ICU1+1 ; \
  64.     inb $0x84,%al ; \
  65.     inb $ IO_ICU2+1, %al ; /* next, get high order mask */ \
  66.     xchgb   %dh, %al ;  /* switch the old with the new */ \
  67.     orb %dh, %al ;  /* finally, or it in! */ \
  68.     outb    %al, $ IO_ICU2+1 ; \
  69.     inb $0x84, %al ; \
  70.     pushl   %edx ;      /* save old mask for when we return */ \
  71.     pushl   $ unit ;    /* finish off interrupt frame with unit # */ \
  72.     sti ;           /* and allow other unmasked interrupts */
  73. ...
  74.  
  75.  
  76.  
  77. [LISTING TWO]
  78.  
  79. /* AT/386 -- Interrupt vector routines -- Generated by config program  */ 
  80.  
  81. #include    "machine/isa/isa.h"
  82. #include    "machine/isa/icu.h"
  83.  
  84. #define VEC(name)   .align 4; .globl _V/**/name; _V/**/name:
  85.     .globl  _hardclock
  86. VEC(clk)
  87.     INTR(0, ___highmask__, 0)
  88.     call    _hardclock 
  89.     INTREXIT1
  90.  
  91.     .globl _wdintr, _wd0mask
  92.     .data
  93. _wd0mask:   .long 0
  94.     .text
  95. VEC(wd0)
  96.     INTR(0, ___biomask__, 1)
  97.     call    _wdintr
  98.     INTREXIT2
  99.  
  100.     .globl _fdintr, _fd0mask
  101.     .data
  102. _fd0mask:   .long 0
  103.     .text
  104. VEC(fd0)
  105.     INTR(0, ___biomask__, 2)
  106.     call    _fdintr
  107.     INTREXIT1
  108.  
  109.     .globl _cnrint, _cn0mask
  110.     .data
  111. _cn0mask:   .long 0
  112.     .text
  113. VEC(cn0)
  114.     INTR(0, ___ttymask__, 3)
  115.     call    _cnrint
  116.     INTREXIT1
  117.  
  118.     .globl _npxintr, _npx0mask
  119.     .data
  120. _npx0mask:  .long 0
  121.     .text
  122. VEC(npx0)
  123.     INTR(0, _npx0mask, 4)
  124.     call    _npxintr
  125.     INTREXIT2
  126.  
  127.     .globl _comintr, _com0mask
  128.     .data
  129. _com0mask:  .long 0
  130.     .text
  131. VEC(com0)
  132.     INTR(0, ___ttymask__, 5)
  133.     call    _comintr
  134.     INTREXIT1
  135.  
  136.     .globl _weintr, _we0mask
  137.     .data
  138. _we0mask:   .long 0
  139.     .text
  140. VEC(we0)
  141.     INTR(0, ___netmask__, 6)
  142.     call    _weintr
  143.     INTREXIT1
  144.  
  145.     .globl _lptintr, _lpt0mask
  146.     .data
  147. _lpt0mask:  .long 0
  148.     .text
  149. VEC(lpt0)
  150.     INTR(0, ___ttymask__, 7)
  151.     call    _lptintr
  152.     INTREXIT1
  153.  
  154.     
  155.  
  156.  
  157. [LISTING THREE]
  158.  
  159. /* [Excerpted from /sys/i386/isa/icu.h] */
  160.  ...
  161. /* First eight interrupts (ICU1) */
  162. #define INTREXIT1   \
  163.     jmp doreti
  164. /* Second eight interrupts (ICU2) */
  165. #define INTREXIT2   \
  166.     jmp doreti
  167.  ...
  168. /* [Excerpted from /sys/i386/isa/icu.s] */
  169.  ...
  170. /* Handle return from interrupt after device handler finishes  */
  171. doreti:
  172.     /* move to a trap frame */
  173.     cli             /* interrupts off while we work ... */
  174.     popl    %ebx            /* remove unit number */
  175.     popl    %eax            /* get previous priority mask */
  176.  
  177.     /* restore previous mask */
  178.     movw    %ax, %cx
  179.     outb    %al, $ IO_ICU1+1
  180.     inb $0x84, %al
  181.     movb    %ah, %al
  182.     outb    %al, $ IO_ICU2+1
  183.     inb $0x84, %al
  184.  
  185.     /* are we at interrupt level / nested interrupt already ? */
  186.     cmpw    ___nonemask__, %cx
  187.     jne 3f
  188.  
  189.     /* do we need to process an network software interrupt ? */
  190.     cmpl    $0, _netisr
  191.     je  2f
  192.     btsl    $ NETISR_PROCESS, _netisr
  193.     jb  2f
  194.  
  195. #include "../net/netisr.h"
  196. #define DOCALL(n, s, c) ; \
  197.     .globl  c ;  \
  198.     btrl    $ s , n ;  \
  199.     jnb 1f ; \
  200.     call    c ; \
  201. 1:
  202.     /* process a network software interrupt */
  203.     sti
  204.     DOCALL(_netisr, NETISR_RAW, _rawintr)
  205. #ifdef INET
  206.     DOCALL(_netisr, NETISR_IP, _ipintr)
  207. #endif
  208. #ifdef IMP
  209.     DOCALL(_netisr, NETISR_IMP, _impintr)
  210. #endif
  211. #ifdef NS
  212.     DOCALL(_netisr, NETISR_NS, _nsintr)
  213. #endif
  214.     btrl    $ NETISR_PROCESS, _netisr
  215. 2:
  216.     /* do we need to process a software clock "interrupt" */
  217.     cli
  218.     btrl    $ SCLK_NEED, ___softclock__
  219.     jnb 1f
  220.     btsl    $ SCLK_PROCESS, ___softclock__
  221.     jb  1f
  222.  
  223.     /* process a software clock "interrupt" */
  224.     sti
  225.     pushl   ___nonemask__   /* to an interrupt frame again */
  226.     pushl   %ebx
  227.     call    _softclock
  228.     popl    %eax        /* back to trap frame for possible AST */
  229.     popl    %eax
  230.     btrl    $ SCLK_PROCESS, ___softclock__
  231. 1:
  232.     /* see if we need to process an AST (rescheduling) fault */
  233.     cmpw    $0x1f, tCS*4(%esp) /* were we executing from a user mode ... */
  234.     jne 3f      /* ... code selector? */
  235.     DOCALL(___ast__, AST_NEED, _trap);
  236. 3:
  237.     /* restore the state and return */
  238.     popl    %es
  239.     popl    %ds
  240.     popal
  241.     nop
  242.     addl    $8, %esp
  243.     iret
  244.  ...
  245.  
  246.  
  247.